/* Name: Sprite
 * Author: John Gideon
 * Date: 5-1-12
 * Description: Allows for the importing, caching, and drawing of images to the screen (called sprites)
 * Revisions: See Subversion logs at http://code.google.com/p/software-engineering-2012/source/list
 */

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import javax.imageio.ImageIO;

public class Sprite {
	private static HashMap<String,Sprite> sprites = new HashMap<String,Sprite>();
	private Image image;
	
	// Sets the image to the passed parameter
	public Sprite(Image pImage) {
		image = pImage;		
	}
	
	// Checks if image to load already exists in cache. If it does, return Sprite. Else, load image and create sprite returning reference.
	public static Sprite load(String path) {
		// http://www.cokeandcode.com/info/tut2d.html
		if (sprites.get(path) != null) {
			return (Sprite) sprites.get(path);
		} else {
			Image sourceImage = null;
			try {
				URL url = new URL(new File(System.getProperty("user.dir")+path).toURI().toURL(), "");
				sourceImage = ImageIO.read(url);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			// create an accelerated image of the right size to store our sprite in
			GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
			Image pImage = gc.createCompatibleImage(sourceImage.getWidth(null),sourceImage.getHeight(null),Transparency.BITMASK);
			// draw our source image into the accelerated image
			pImage.getGraphics().drawImage(sourceImage,0,0,null);
			Sprite newSprite = new Sprite(pImage);
			sprites.put(path,newSprite);
			return newSprite;
		}
	}
	
	// Draws the image on the screen in the specified location
	public void draw(Graphics2D g,int x,int y) {
		g.drawImage(image,x-(int)(getWidth()/2.0f),y-(int)(getHeight()/2.0f),null);
	}
	
	// Draws the image on the screen in the specified location applying rotation and uniform scaling
	public void draw(Graphics2D g, int x, int y, float rot, float scale) {
		AffineTransform saveForm = g.getTransform();
        AffineTransform tfm = new AffineTransform();
        tfm.translate(x, y);
        tfm.rotate(rot,0,0);
        tfm.translate(-getWidth()*scale/2.0f, -getHeight()*scale/2.0f);
        tfm.scale(scale, scale);
        g.transform(tfm);
		g.drawImage(image,0,0,null);
        g.setTransform(saveForm);
	}
	
	public int getWidth() {return image.getWidth(null);}
	public int getHeight() {return image.getHeight(null);}
	
}
